
package com.hlkj.pay.app.merchant.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.executor.ExtensionExecutor;
import com.hlkj.framework.extension.scenario.BizScenario;
import com.hlkj.pay.app.merchant.IMerchantChannelAppService;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantReportExtPt;
import com.hlkj.pay.app.merchant.ext.dto.access.MerchantAccessCallBackDto;
import com.hlkj.pay.app.merchant.ext.dto.access.MerchantBusinessCallBackDto;
import com.hlkj.pay.app.merchant.ext.dto.access.MerchantChannelSplitCallBackDto;
import com.hlkj.pay.app.merchant.ext.dto.report.MerchantReportAllotCallBackDto;
import com.hlkj.pay.app.merchant.ext.dto.report.MerchantReportAmountCallBackDto;
import com.hlkj.pay.app.merchant.ext.dto.report.MerchantReportCallBackDto;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.common.PayResultCode;
import com.hlkj.pay.common.constants.MqConstant;
import com.hlkj.pay.config.ExtRocketMQTemplate;
import com.hlkj.pay.dto.merchant.MerchantAccessInfoPageQueryDto;
import com.hlkj.pay.dto.merchant.MerchantAccessSignLink;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantReportAmountDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantReportInfoDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.service.merchant.IMerchantAccessAuthService;
import com.hlkj.pay.service.merchant.IMerchantAccessService;
import com.hlkj.pay.service.merchant.IMerchantReportAmountService;
import com.hlkj.pay.service.merchant.IMerchantReportService;
import com.hlkj.pay.service.pay.IPayChannelService;
import com.hlkj.pay.service.pay.IProviderService;
import com.hlkj.pay.util.HttpRequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author HlpayTeam
 * @date 2024/09/29 16:44
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MerchantChannelAppServiceImpl implements IMerchantChannelAppService {

    private final ExtensionExecutor extensionExecutor;

    private final IProviderService providerService;

    private final IMerchantAccessService merchantAccessService;

    private final IMerchantReportService merchantReportService;

    private final IMerchantReportAmountService merchantReportAmountService;

    private final IPayChannelService payChannelService;

    private final MerchantAccessStatusProcessHandler merchantAccessStatusProcessHandler;

    private final CommonChannelCallHandler commonChannelCallHandler;

    private final ExtRocketMQTemplate extRocketMQTemplate;

    private final IMerchantAccessAuthService merchantAccessAuthService;

    @Override
    public String accessCallBack(String channelCode, String providerCode, HttpServletRequest request) {
        // String accessCallBody = HttpRequestUtil.requestParams(request);
        log.info("进件结果回调 channelCode:{},providerCode:{}", channelCode, providerCode);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, null, null, null, null,
                        CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            // 参数转换
            MerchantAccessCallBackDto accessCallBackDto = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.accessCallBackParamsParse(request, providerChannelConfigDO));
            accessCallBackDto.setServiceName(providerChannelConfigDO.getChannelCode() + "_access_callback");
            MerchantAccessInfoDO merchantAccessInfoDO = null;
            if (StringUtils.isNotEmpty(accessCallBackDto.getRequestId())) {
                merchantAccessInfoDO = merchantAccessService.queryByRequestId(accessCallBackDto.getRequestId());
            } else if (StringUtils.isNotEmpty(accessCallBackDto.getApplyNo())) {
                MerchantAccessInfoPageQueryDto merchantAccessInfoPageQueryDto = new MerchantAccessInfoPageQueryDto();
                merchantAccessInfoPageQueryDto.setProviderCode(providerCode);
                merchantAccessInfoPageQueryDto.setChannelCode(channelCode);
                merchantAccessInfoPageQueryDto.setApplyNo(accessCallBackDto.getApplyNo());
                List<MerchantAccessInfoDO> merchantAccessInfoList = merchantAccessService.queryList(merchantAccessInfoPageQueryDto);
                if (!CollectionUtils.isEmpty(merchantAccessInfoList)) {
                    merchantAccessInfoDO = merchantAccessInfoList.get(0);
                }
            } else if(StringUtils.isNotEmpty(accessCallBackDto.getSubMchId())) {
                merchantAccessInfoDO = merchantAccessService.queryBySubMchId(accessCallBackDto.getSubMchId());
            }
            if (merchantAccessInfoDO == null) {
                log.info("进件结果回调没有对应的数据 channelCode:{},providerCode:{}", channelCode, providerCode);
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, accessCallBackDto.getRequestId(), accessCallBackDto.getServiceName(),
                        accessCallBackDto.getCallBackBody(), null, CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
            }
            // 非渠道审核中 直接返回处理成功
            // if (MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE.getCode() >
            // merchantAccessInfoDO.getStatus()
            // ||
            // MerchantEnum.ACCESS_STATUS.APPROVE_SUCCESS.getCode().equals(merchantAccessInfoDO.getStatus()))
            // {
            if (StringUtils.isNotEmpty(merchantAccessInfoDO.getSubMchId())
                    && (accessCallBackDto.getAccessStatus() != null && merchantAccessInfoDO.getStatus() > accessCallBackDto.getAccessStatus().getCode())) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, accessCallBackDto.getRequestId(), accessCallBackDto.getServiceName(),
                        accessCallBackDto.getCallBackBody(), accessCallBackDto, CommonResult.success(accessCallBackDto.getRequestId()));
            }
            Long accessId = merchantAccessInfoDO.getId();
            MerchantAccessInfoDO updateAccessInfoDO = new MerchantAccessInfoDO();
            updateAccessInfoDO.setId(accessId);
            if (accessCallBackDto.getAccessStatus() != null) {
                updateAccessInfoDO.setStatus(accessCallBackDto.getAccessStatus().getCode());
            }
            List<MerchantAccessSignLink> signLinks = null;
            if(StrUtil.isNotEmpty(accessCallBackDto.getAgreementSignUrl())){
                signLinks = new ArrayList<>();
                MerchantAccessSignLink merchantAccessSignLink = new MerchantAccessSignLink();
                merchantAccessSignLink.setLink(accessCallBackDto.getAgreementSignUrl());
                signLinks.add(merchantAccessSignLink);
            }

            if(accessCallBackDto.getAuditStatus() != null){
                updateAccessInfoDO.setAuditStatus(accessCallBackDto.getAuditStatus().getCode());
            }
            updateAccessInfoDO.setSubMchId(accessCallBackDto.getSubMchId());
            updateAccessInfoDO.setRemark(accessCallBackDto.getRemark());
            // 更新主表状态
            merchantAccessService.updateAccessInfo(updateAccessInfoDO, signLinks);
            // 更新请求日志对应的状态
            if (accessCallBackDto.isProcessStatus()) {
                // 下一个步骤处理
                merchantAccessStatusProcessHandler.processAccess(accessId);
            }
            return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, accessCallBackDto.getRequestId(), accessCallBackDto.getServiceName(),
                    accessCallBackDto.getCallBackBody(), accessCallBackDto, CommonResult.success(accessCallBackDto.getRequestId()));
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String accessCallBack(String channelCode, HttpServletRequest request) {
        try {
            String accessCallBody = HttpRequestUtil.requestBodyParams(request);

            log.info("进件结果回调对应的数据 channelCode:{},accessCallBody:{}", channelCode, accessCallBody);
            List<ProviderChannelConfigDO> channelConfigDOList = providerService.queryConfigListByChannel(channelCode);
            CommonResult<String> commonResult = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.accessCallbackParse(accessCallBody, channelConfigDOList));
            if (commonResult.isSuccess()) {
                // 获取通道配置
                MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.queryBySubMchId(commonResult.getData());
                if (merchantAccessInfoDO == null) {
                    log.info("进件结果回调没有对应的数据 channelCode:{}", channelCode);
                    return commonChannelCallHandler.processAccessLogAndResponse(channelCode, "", "", "",
                            "", null, CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
                }
                return accessCallBack(channelCode, merchantAccessInfoDO.getProviderCode(), request);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String businessApproveCallBack(String channelCode, String providerCode, HttpServletRequest request) {
        String accessCallBody = HttpRequestUtil.requestBodyParams(request);
        log.info("业务开通回调 channelCode:{},providerCode:{},accessCallBody:{}", channelCode, providerCode, accessCallBody);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, null, null, accessCallBody, null,
                        CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));

            }
            // 参数转换
            MerchantBusinessCallBackDto merchantBusinessCallBackDto = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.businessCallBackParamsParse(accessCallBody, providerChannelConfigDO));
            PayChannelRequestDO payChannelRequestDO = payChannelService.queryRequestByRequestId(merchantBusinessCallBackDto.getRequestId());
            if (payChannelRequestDO == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, merchantBusinessCallBackDto.getRequestId(),
                        merchantBusinessCallBackDto.getServiceName(), accessCallBody, merchantBusinessCallBackDto,
                        CommonResult.error(MerchantResultCode.MERCHANT_ACCESS_NOT_EXIST));
            }
            String relationId = payChannelRequestDO.getRelationId();
            Long accessId = Long.parseLong(relationId);
            // 获取请求记录
            MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(accessId);
            // 非配置中 直接返回处理成功
            if (!MerchantEnum.ACCESS_STATUS.WAIT_SETTING.getCode().equals(merchantAccessInfoDO.getStatus())) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, merchantBusinessCallBackDto.getRequestId(),
                        merchantBusinessCallBackDto.getServiceName(), accessCallBody, merchantBusinessCallBackDto,
                        CommonResult.success(merchantBusinessCallBackDto.getRequestId()));
            }
            // 更新主表状态
            merchantAccessService.updateStatus(accessId, merchantBusinessCallBackDto.getAccessStatus(), merchantBusinessCallBackDto.getRemark());
            // 更新请求日志对应的状态
            payChannelService.updateRequestStatus(payChannelRequestDO.getId(), merchantBusinessCallBackDto.getAccessStatus().getCode());
            if (merchantBusinessCallBackDto.isProcessStatus()) {
                // 下一个步骤处理
                merchantAccessStatusProcessHandler.processAccess(accessId);
            }
            return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, merchantBusinessCallBackDto.getRequestId(),
                    merchantBusinessCallBackDto.getServiceName(), accessCallBody, merchantBusinessCallBackDto, CommonResult.success(merchantBusinessCallBackDto.getRequestId()));
        }
        catch (Exception e) {
            log.error("businessApproveCallBack error:{}", e, e.getMessage());
        }
        return "";
    }

    @Override
    public String businessSuccessCallBack(String channelCode, String providerCode, HttpServletRequest request) {
        String accessCallBody = HttpRequestUtil.requestBodyParams(request);
        log.info("业务开通成功回调 channelCode:{},providerCode:{},accessCallBody:{}", channelCode, providerCode, accessCallBody);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode),
                        ex -> ex.callBackResponse(CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS)));
            }
            // 参数转换
            MerchantBusinessCallBackDto businessCallBackDto = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.businessCallBackParamsParse(accessCallBody, providerChannelConfigDO));
            // 只记录日志
            return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, businessCallBackDto.getRequestId(), businessCallBackDto.getServiceName(),
                    accessCallBody, businessCallBackDto, CommonResult.success(businessCallBackDto.getRequestId()));
        }
        catch (Exception e) {
            log.error("businessSuccessCallBack error:{}", e, e.getMessage());
        }
        return "";
    }

    @Override
    public String reportApproveCallBack(String channelCode, String providerCode, HttpServletRequest request) {
        log.info("报备结果回调 channelCode:{},providerCode:{}", channelCode, providerCode);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, null, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            // 参数转换
            MerchantReportCallBackDto merchantReportCallBackDto = extensionExecutor.execute(ChannelMerchantReportExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.submitReportCallBackParamsParse(request, providerChannelConfigDO));
            if (MerchantEnum.REPORT_STATUS.CHANNEL_APPROVE.getCode().equals(merchantReportCallBackDto.getReportStatus().getCode())) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, merchantReportCallBackDto.getRequestId(),
                        merchantReportCallBackDto.getCallBackBody(), CommonResult.success(merchantReportCallBackDto.getRequestId()));
            }
            MerchantReportInfoDO merchantReportInfoDO = merchantReportService.queryByRequestId(merchantReportCallBackDto.getRequestId());
            // 非渠道审核中 直接返回处理成功
            if (MerchantEnum.ACCESS_STATUS.CHANNEL_APPROVE.getCode() > merchantReportInfoDO.getStatus()
                    || MerchantEnum.ACCESS_STATUS.APPROVE_SUCCESS.getCode().equals(merchantReportInfoDO.getStatus())) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, merchantReportCallBackDto.getRequestId(),
                        merchantReportCallBackDto.getCallBackBody(), CommonResult.success(merchantReportCallBackDto.getRequestId()));
            }
            Long reportId = merchantReportInfoDO.getId();
            // 验签不通过 通过主查解决
            if (!merchantReportCallBackDto.isVerifySign()) {
                log.info("报备结果回调 签名验证不通过,通过异步主查获取当前审核状态:{}", reportId);
                // 下一个步骤处理
                sendMerchantReportMessage(reportId);
            }
            else {
                MerchantReportInfoDO updateAccessInfoDO = new MerchantReportInfoDO();
                updateAccessInfoDO.setId(reportId);
                if (merchantReportCallBackDto.getReportStatus() != null) {
                    updateAccessInfoDO.setStatus(merchantReportCallBackDto.getReportStatus().getCode());
                }
                if (merchantReportCallBackDto.getAuditStatus() != null) {
                    updateAccessInfoDO.setAuditStatus(merchantReportCallBackDto.getAuditStatus().getCode());
                }
                updateAccessInfoDO.setSubMchId(merchantReportCallBackDto.getSubMchId());
                updateAccessInfoDO.setMessage(merchantReportCallBackDto.getRemark());
                if (StringUtils.isNotEmpty(merchantReportCallBackDto.getExtendA())) {
                    updateAccessInfoDO.setExtendA(merchantReportCallBackDto.getExtendA());
                }
                if (StringUtils.isNotEmpty(merchantReportCallBackDto.getVirtualAccountNo())) {
                    updateAccessInfoDO.setVirtualAccountNo(merchantReportCallBackDto.getVirtualAccountNo());
                }
                // 更新主表状态
                merchantReportService.updateReportInfo(updateAccessInfoDO);
                // 更新请求日志对应的状态
                if (merchantReportCallBackDto.isProcessStatus()) {
                    // 下一个步骤处理
                    sendMerchantReportMessage(reportId);
                }
            }
            return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, merchantReportCallBackDto.getRequestId(),
                    merchantReportCallBackDto.getCallBackBody(), CommonResult.success(merchantReportCallBackDto.getRequestId()));
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String reportApproveCallBack(String channelCode, HttpServletRequest request) {
//        try {
//            String accessCallBody = HttpRequestUtil.requestBodyParams(request);
//            JSONObject obj = JSONUtil.parseObj(accessCallBody);
//            JSONObject dataObj = obj.getJSONObject("pdata");
//            MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.queryBySubMchId(dataObj.getStr("CUST_ID"));
//            if (merchantAccessInfoDO == null) {
//                log.info("报备结果回调没有获取到商户信息 channelCode:{},accessCallBody:{}", channelCode, accessCallBody);
//                return commonChannelCallHandler.processReportLogAndResponse(channelCode, "", "",
//                        "", CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
//            }
//            return reportApproveCallBack(channelCode, merchantAccessInfoDO.getProviderCode(), request);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        return "";
    }

    @Override
    public String reportAmountCallBack(String channelCode, HttpServletRequest request) {
        log.info("报备电子户入金通知 channelCode:{}", channelCode);
        try {
            // 参数转换
            MerchantReportAmountCallBackDto merchantReportAmountCallBackDto = extensionExecutor.execute(ChannelMerchantReportExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.reportAmountCallBackParamsParse(request));
            if (merchantReportAmountCallBackDto == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, null, null, merchantReportAmountCallBackDto.getServiceName(), null,
                        merchantReportAmountCallBackDto, CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
            }
            merchantReportAmountCallBackDto.setServiceName(channelCode + "_report_amount_callback");
            MerchantReportAmountDO merchantReportAmount = merchantReportAmountCallBackDto.getMerchantReportAmount();
            MerchantReportInfoDO merchantReportInfoDO = merchantReportService.queryByExtendB(merchantReportAmount.getAcctId(), channelCode);
            if (merchantReportInfoDO == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, null, null, merchantReportAmountCallBackDto.getServiceName(), null,
                        merchantReportAmountCallBackDto, CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
            }
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(merchantReportInfoDO.getProviderCode(), channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, merchantReportInfoDO.getProviderCode(), null, null, null, null,
                        CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            boolean verifyCallBackParamsParse = extensionExecutor.execute(ChannelMerchantReportExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.verifyCallBackParamsParse(merchantReportAmountCallBackDto.getCallBackBody(), providerChannelConfigDO));
            Long reportId = merchantReportInfoDO.getId();
            MerchantReportInfoDO updateAccessInfoDO = new MerchantReportInfoDO();
            updateAccessInfoDO.setId(reportId);
            if (!verifyCallBackParamsParse) {
                log.info("报备电子户入金通知 签名验证不通过,通过异步主查获取当前余额状态:{}", reportId);
                // updateAccessInfoDO.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.BANK_BALANCE.getCode());
                // 更新主表状态
                // merchantReportService.updateReportInfo(updateAccessInfoDO);
            }
            updateAccessInfoDO.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.BANK_ALLOT.getCode());
            // 更新主表状态
            merchantReportService.updateReportInfo(updateAccessInfoDO);
            merchantReportAmount.setReportId(merchantReportInfoDO.getId());
            merchantReportAmount.setSubMchId(merchantReportInfoDO.getSubMchId());
            merchantReportAmountService.addReportAmount(merchantReportAmount);
            // 更新请求日志对应的状态
            // 下一个步骤处理
            sendMerchantReportMessage(reportId);
            return commonChannelCallHandler.processAccessLogAndResponse(channelCode, merchantReportInfoDO.getProviderCode(), merchantReportAmount.getAcctId(),
                    merchantReportAmountCallBackDto.getServiceName(), merchantReportAmountCallBackDto.getCallBackBody(), merchantReportAmountCallBackDto, CommonResult.success());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String reportAmountCallBack(String channelCode, String providerCode, HttpServletRequest request) {
        log.info("报备电子户入金通知 channelCode:{},providerCode:{}", channelCode, providerCode);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, null, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            // 参数转换
            CommonResult<MerchantReportAmountCallBackDto> commonResult = extensionExecutor.execute(ChannelMerchantReportExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.reportAmountCallBackParamsParse(request, providerChannelConfigDO));
            if (!commonResult.isSuccess()) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, null, commonResult);
            }
            MerchantReportAmountCallBackDto merchantReportAmountCallBackDto = commonResult.getData();
            if (merchantReportAmountCallBackDto == null) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, merchantReportAmountCallBackDto.getCallBackBody(),
                        CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
            }
            MerchantReportAmountDO merchantReportAmount = merchantReportAmountCallBackDto.getMerchantReportAmount();
            MerchantReportInfoDO merchantReportInfoDO = merchantReportService.queryByExtendB(merchantReportAmount.getAcctId(), channelCode);
            if (merchantReportInfoDO == null) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, merchantReportAmountCallBackDto.getCallBackBody(),
                        CommonResult.error(CommonResultCode.DATA_NOT_EXIST));
            }
            Long reportId = merchantReportInfoDO.getId();
            MerchantReportInfoDO updateAccessInfoDO = new MerchantReportInfoDO();
            updateAccessInfoDO.setId(reportId);
            updateAccessInfoDO.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.BANK_ALLOT.getCode());
            // 更新主表状态
            merchantReportService.updateReportInfo(updateAccessInfoDO);
            merchantReportAmount.setReportId(merchantReportInfoDO.getId());
            merchantReportAmount.setSubMchId(merchantReportInfoDO.getSubMchId());
            merchantReportAmountService.addReportAmount(merchantReportAmount);
            // 更新请求日志对应的状态
            // 下一个步骤处理
            sendMerchantReportMessage(reportId);
            return commonChannelCallHandler.processReportLogAndResponse(channelCode, merchantReportInfoDO.getProviderCode(), merchantReportAmount.getAcctId(),
                    merchantReportAmountCallBackDto.getCallBackBody(), CommonResult.success());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String easySplitCallBack(String channelCode, String providerCode, String requestId, HttpServletRequest request) {
        log.info("易生拆分回调 channelCode:{},providerCode:{}", channelCode, providerCode);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, null, null, null, null,
                        CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            // 参数转换
            MerchantChannelSplitCallBackDto merchantReportCallBackDto = extensionExecutor.execute(ChannelMerchantAccessExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.easySplitCallBackParamsParse(request, providerChannelConfigDO));
            merchantReportCallBackDto.setServiceName(providerChannelConfigDO.getChannelCode() + "_split_callback");
//            // 更新请求日志对应的状态
            if (merchantReportCallBackDto.isProcessStatus()) {
                List<MerchantAccessAuthDO> merchantAccessAuthDOList = merchantReportCallBackDto.getMerchantAccessAuthDOList();
                MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.queryByRequestId(requestId);
                if (merchantAccessInfoDO == null) {
                    return "";
                }
                if (CollectionUtils.isNotEmpty(merchantAccessAuthDOList)) {
                    merchantAccessAuthDOList.stream().forEach(merchantAccessAuthDO -> {
                        merchantAccessAuthDO.setAccessId(merchantAccessInfoDO.getId());
                        merchantAccessAuthDO.setSn(merchantAccessInfoDO.getSn());
                    });
                    merchantAccessAuthService.saveMerchantAccessAuth(merchantAccessAuthDOList);
                }
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, requestId, merchantReportCallBackDto.getServiceName(), null, null,
                        CommonResult.success(providerChannelConfigDO));
            }
            else {
                CommonResult<ProviderChannelConfigDO> commonResult = CommonResult.error(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SPLIT_ERROR);
                commonResult.setData(providerChannelConfigDO);
                return commonChannelCallHandler.processAccessLogAndResponse(channelCode, providerCode, requestId, merchantReportCallBackDto.getServiceName(), null, null,
                        commonResult);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String testCallBack(String channelCode, HttpServletRequest request) {
        return commonChannelCallHandler.processAccessLogAndResponse(channelCode, null, null, null, null, null, CommonResult.success());
    }

    @Override
    public String productUpdateCallBack(String channelCode, String providerCode, String requestId, HttpServletRequest request) {
        log.info("进件修改产品通知 channelCode:{},providerCode:{}", channelCode, providerCode);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processSettleLogAndResponse(channelCode, providerCode, null, null, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }

            return commonChannelCallHandler.processSettleLogAndResponse(channelCode, providerCode, null, null, CommonResult.success());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public String reportAllotCallBack(String channelCode, String providerCode, HttpServletRequest request) {
        log.info("资金调拨结果通知 channelCode:{},providerCode:{}", channelCode, providerCode);
        try {
            // 获取通道配置
            ProviderChannelConfigDO providerChannelConfigDO = providerService.queryConfig(providerCode, channelCode);
            if (providerChannelConfigDO == null) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, null, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            // 参数转换
            MerchantReportAllotCallBackDto merchantReportCallBackDto = extensionExecutor.execute(ChannelMerchantReportExtPt.class, BizScenario.valueOf(channelCode),
                    ex -> ex.reportAllotCallBackParamsParse(request, providerChannelConfigDO));
            MerchantReportAmountDO merchantReportAmountDO = merchantReportAmountService.queryAmountByCode(merchantReportCallBackDto.getRequestId());
            if (merchantReportAmountDO == null) {
                return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, null, null, CommonResult.error(PayResultCode.PROVIDER_CHANNEL_NOT_EXITS));
            }
            MerchantReportInfoDO merchantReportInfoDO = merchantReportService.detail(merchantReportAmountDO.getReportId());

            Long reportId = merchantReportInfoDO.getId();
            // 验签不通过 通过主查解决
            MerchantReportInfoDO updateAccessInfoDO = new MerchantReportInfoDO();
            updateAccessInfoDO.setId(reportId);
            if (!merchantReportCallBackDto.isVerifySign()) {
                log.info("资金调拨结果通知 签名验证不通过,通过异步主查获取当前审核状态:{}", reportId);
                updateAccessInfoDO.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.BANK_ALLOT.getCode());
                // 下一个步骤处理
                sendMerchantReportMessage(reportId);
            }
            else {
                updateAccessInfoDO.setAuditStatus(MerchantEnum.REPORT_CHANNEL_CONFIG_STATUS.PAYMENT.getCode());
                // 更新主表状态
                merchantReportService.updateReportInfo(updateAccessInfoDO);
                MerchantReportAmountDO merchantReportAmount = new MerchantReportAmountDO();
                merchantReportAmount.setId(merchantReportAmountDO.getId());
                merchantReportAmount.setAmount(merchantReportCallBackDto.getOrderAmount());
                merchantReportAmount.setRealAmount(merchantReportCallBackDto.getRealAmount());
                merchantReportAmount.setProcessStatus(MerchantEnum.REPORT_AMOUNT_PROCESS_STATUS.PAYMENT.getCode());
                if (!merchantReportCallBackDto.isProcessStatus()) {
                    merchantReportAmount.setRemark(merchantReportCallBackDto.getRemark());
                }
                merchantReportAmountService.updateReportAmount(merchantReportAmount);
                if (merchantReportCallBackDto.isProcessStatus()) {
                    // 更新请求日志对应的状态
                    // 下一个步骤处理
                    sendMerchantReportMessage(reportId);
                }
            }
            return commonChannelCallHandler.processReportLogAndResponse(channelCode, providerCode, merchantReportCallBackDto.getRequestId(),
                    merchantReportCallBackDto.getCallBackBody(), CommonResult.success(merchantReportCallBackDto.getRequestId()));
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    void sendMerchantReportMessage(Long id) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        String jsonString = JsonUtils.toJsonString(map);
        log.info("sendMerchantReportMessage:{}", jsonString);
        extRocketMQTemplate.send(MqConstant.MERCHANT_REPORT_STATUS_TOPIC, jsonString);
    }

}
